package cn.openea.perpartner.link.web.service.impl;

import cn.openea.perpartner.common.core.exception.ServiceException;
import cn.openea.perpartner.link.constant.enums.AppType;
import cn.openea.perpartner.link.util.Tools;
import cn.openea.perpartner.link.util.UserContext;
import cn.openea.perpartner.link.web.entity.ShareLinkConfig;
import cn.openea.perpartner.link.web.entity.vo.AddShareLinkConfigVo;
import cn.openea.perpartner.link.web.entity.vo.ShareLinkSearchVo;
import cn.openea.perpartner.link.web.mapper.ShareLinkConfigMapper;
import cn.openea.perpartner.link.web.service.IShareLinkConfigService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.NonNull;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.List;


@Service("shareLinkConfigService")
public class ShareLinkConfigServiceImpl extends ServiceImpl<ShareLinkConfigMapper, ShareLinkConfig> implements IShareLinkConfigService {

    @Override
    public List<ShareLinkConfig> findListBySearchVo(ShareLinkSearchVo shareLinkSearchVo) {
        LambdaQueryWrapper<ShareLinkConfig> queryWrapper = buildQueryWrapper(shareLinkSearchVo);
        // 根据点击量进行排序
        queryWrapper.orderByDesc(ShareLinkConfig::getVisitsNum);
        return baseMapper.selectList(queryWrapper);
    }

    @Override
    public ShareLinkConfig findByAppTypeAndName(@NonNull AppType appType, String name) {
        return baseMapper.selectOne(new LambdaQueryWrapper<ShareLinkConfig>()
                .eq(ShareLinkConfig::getAppType, appType.getCode())
                .eq(ShareLinkConfig::getLinkName, name));
    }

    @Cacheable(cacheNames = "findOneByKey", key = "#root.methodName + #key", cacheManager = "defaultRedisCacheManager")
    @Override
    public ShareLinkConfig findOneByKey(String key) {
        return baseMapper.selectOne(new LambdaQueryWrapper<ShareLinkConfig>()
                .eq(ShareLinkConfig::getShareKey, key));
    }

    private LambdaQueryWrapper<ShareLinkConfig> buildQueryWrapper(ShareLinkSearchVo searchVo) {
        if (searchVo == null) {
            return null;
        }
        LambdaQueryWrapper<ShareLinkConfig> queryWrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(searchVo.getShareKey())) {
            queryWrapper.eq(ShareLinkConfig::getShareKey, searchVo.getShareKey());
        }
        if (StringUtils.isNotBlank(searchVo.getAppType())) {
            queryWrapper.eq(ShareLinkConfig::getAppType, searchVo.getAppType());
        }
        if (StringUtils.isNotBlank(searchVo.getLinkName())) {
            queryWrapper.like(ShareLinkConfig::getLinkName, searchVo.getLinkName());
        }
        if (StringUtils.isNotBlank(searchVo.getCreateUser())) {
            queryWrapper.like(ShareLinkConfig::getCreateUser, searchVo.getCreateUser());
        }
        return queryWrapper;
    }

    @Override
    public void addShareLinkConfig(@NonNull AddShareLinkConfigVo addVo) {
        AppType appType = AppType.getByCode(addVo.getAppType());
        if (appType == null) {
            throw new ServiceException("分享链接所属平台不存在");
        }
        ShareLinkConfig oldShareLink = findByAppTypeAndName(appType, addVo.getLinkName());
        if (oldShareLink != null) {
            throw new ServiceException(addVo.getLinkName() + "已存在");
        }
        baseMapper.insert(ShareLinkConfig.builder()
                .linkName(addVo.getLinkName())
                .shareKey(Tools.getRandom(6))
                .pagePath(addVo.getPagePath())
                .appType(appType.getCode())
                .createUser(UserContext.getUserId())
                .build());

    }

    @CacheEvict(cacheNames = "findOneByKey", key = "'findOneByKey' + #oldShareLinkConfig.shareKey", cacheManager = "defaultRedisCacheManager")
    @Override
    public void updateShareLinkConfig(@NonNull AddShareLinkConfigVo addVo, @NonNull ShareLinkConfig oldShareLinkConfig) {
        if (oldShareLinkConfig.getId() == null) {
            throw new ServiceException("id 不能为空");
        }
        AppType appType = AppType.getByCode(addVo.getAppType());
        if (appType == null) {
            throw new ServiceException("分享链接对应的程序不存在");
        }
        ShareLinkConfig shareLinkConfig = findByAppTypeAndName(appType, addVo.getLinkName());
        if (shareLinkConfig != null && !oldShareLinkConfig.getId().equals(shareLinkConfig.getId())) {
            throw new ServiceException(addVo.getLinkName() + "已存在");
        }
        oldShareLinkConfig.setLinkName(addVo.getLinkName());
        oldShareLinkConfig.setAppType(appType.getCode());
        oldShareLinkConfig.setPagePath(addVo.getPagePath());
        baseMapper.updateById(oldShareLinkConfig);
    }

    @CacheEvict(cacheNames = "findOneByKey", key = "'findOneByKey' + #key", cacheManager = "defaultRedisCacheManager")
    @Override
    public void deleteByKey(String key) {
        baseMapper.updateByShareKey(key);
    }


    @Override
    public void updateVisitsNum(Long id, Integer visitsNum) {
        if (id == null) {
            throw new ServiceException("id 不能为空");
        }
        baseMapper.updateVisitsNum(id, visitsNum);
    }
}